package com.whiteape.book.core.parser;

import com.whiteape.book.core.manager.ParserManager;
import com.whiteape.book.model.bo.ChapterBo;
import com.whiteape.book.model.bo.ChapterContentBo;
import com.whiteape.book.model.dto.CollectionMediaBean;
import com.whiteape.book.model.dto.MediaChapterBean;
import com.whiteape.book.model.dto.SiteSourceBean;
import com.whiteape.book.model.dto.SiteSourceChapterInfoBean;
import com.whiteape.book.net.RetrofitHelper;
import com.whiteape.book.utils.MD5Utils;
import com.whiteape.book.utils.URLUtils;

import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import io.reactivex.Single;
import okhttp3.RequestBody;

public class CatalogParser {

    public static Single<List<MediaChapterBean>> parse(SiteSourceBean siteSourceBean, CollectionMediaBean mediaBean, String html) {
        if (siteSourceBean == null || StringUtils.isEmpty(html)) {
            return Single.create(emitter -> emitter.onError(new Throwable("CatalogParser: check args error")));
        }


        return Single.create(emitter -> {

            List<MediaChapterBean> chapterBoList = parseDirectly(siteSourceBean, mediaBean, html);
            if (chapterBoList.isEmpty()) {
                emitter.onError(new Throwable("no data"));
            }
            emitter.onSuccess(chapterBoList);

        });


    }

    public static List<MediaChapterBean> parseDirectly(SiteSourceBean siteSourceBean, CollectionMediaBean mediaBean, String html) {

        String chapterListUrl = mediaBean.getCatalogUrl();
        String pageNextRule = siteSourceBean.getMediaInfoDetailRule().getCatalogNextPageUrl();
        SiteSourceChapterInfoBean ruleBean = siteSourceBean.getChapterInfoRule();

        List<MediaChapterBean> chapterBoList = new LinkedList<>();
        String listRule = ruleBean.getList();
        Boolean orderAsc = ruleBean.getOrderAsc();
        orderAsc = orderAsc == null ? true : orderAsc;
        List listElements;

        if (!StringUtils.isEmpty(pageNextRule)) {

            listElements = ParserManager.getElementList(chapterListUrl, html, listRule, 1, mediaBean.getVarMap());
            if (listElements == null || listElements.size() == 0) {
                return chapterBoList;
            }
            String nextPage = ParserManager.parseOne(chapterListUrl, html, pageNextRule, mediaBean.getVarMap());

            while (!StringUtils.isEmpty(nextPage)) {
                nextPage = URLUtils.getAbsolutePath(chapterListUrl, nextPage);
                String tmpHtml = requestPage(siteSourceBean, nextPage);
                List tmpList = ParserManager.getElementList(nextPage, tmpHtml, listRule, 1, mediaBean.getVarMap());
                if (tmpList == null || tmpList.size() == 0) {
                    break;
                }
                listElements.addAll(tmpList);


                nextPage = ParserManager.parseOne(nextPage, tmpHtml, pageNextRule, mediaBean.getVarMap());

            }


        } else {
            listElements = ParserManager.getElementList(chapterListUrl, html, listRule, 1, mediaBean.getVarMap());
        }


        //目录排重

        Set<String> idSet = new HashSet<>();
        for (Object element : listElements) {
            MediaChapterBean chapterBo = new MediaChapterBean();
            String doc = ParserManager.getElementString(element);
            if (!StringUtils.isEmpty(ruleBean.getUrl())) {
                String url = ParserManager.parseOne(chapterListUrl, doc, ruleBean.getUrl(), mediaBean.getVarMap());
                if (!url.startsWith("http")) {
                    url = URLUtils.getAbsolutePath(chapterListUrl, url);
                }
//                chapterBo.setCatalogUrl(chapterListUrl);

                chapterBo.setLink(url);
                chapterBo.setId(MD5Utils.strToMd5By16(url));
            }
            chapterBo.setName(ParserManager.parseOne(chapterListUrl, doc, ruleBean.getName(), mediaBean.getVarMap()));
            if ("".equals(chapterBo.getLink()) || "".equals(chapterBo.getName())) {
                continue;
            }
            //排重
            String chapterBoId = chapterBo.getId();
            if (idSet.contains(chapterBoId)) {
                //如果有已经存在的id(url)，那么删除老的，用新的
                chapterBoList.remove(chapterBo);
            } else {
                idSet.add(chapterBo.getId());
            }

            chapterBo.setMediaId(mediaBean.getId());
            chapterBoList.add(chapterBo);
        }
        if (StringUtils.isEmpty(ruleBean.getUrl())) {
            String content = ParserManager.parseOne(chapterListUrl, html, ruleBean.getBatchUrl(), mediaBean.getVarMap());
            String[] urls = content.split(",");
            if (urls.length != chapterBoList.size()) {
                return new ArrayList<>();
            }
            for (int i = 0; i < urls.length; i++) {
                chapterBoList.get(i).setLink(urls[i]);
                chapterBoList.get(i).setId(MD5Utils.strToMd5By16(urls[i]));
            }

        }

        if (!orderAsc) {
            Collections.reverse(chapterBoList);
        }

        return chapterBoList;


    }

    private static String requestPage(SiteSourceBean siteSourceBean, String link) {
        Map<String, String> headerMap = new HashMap<>();
//        headerMap.put("User-Agent", "Mozilla/5.0 (Linux; U; Android 8.0.0; zh-CN; MHA-AL00 Build/HUAWEIMHA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/40.0.2214.89 UCBrowser/11.6.4.950 UWS/2.11.1.50 Mobile Safari/537.36 AliApp(DingTalk/4.5.8) com.alibaba.android.rimet/10380049 Channel/227200 language/zh-CN");
        if (!StringUtils.isEmpty(siteSourceBean.getUserAgent())) {
            headerMap.put("User-Agent", siteSourceBean.getUserAgent());
        }
        headerMap.put("Referer", siteSourceBean.getSiteHostUrl());
        String content;
        String charset = siteSourceBean.getSearch().getCharset();
        try {
            if (link.toUpperCase().contains("@POST:")) {
                //是post请求的
                String[] arr = link.split("(?i)@POST:");
                String url = arr[0];
                String body = arr[1];
                RequestBody requestBody = RequestBody.create(okhttp3.MediaType.parse("text/plain"), body);

                //用bytes获取原始字节，然后转化为对应编码的string
                content = new String(RetrofitHelper.getInstance().getHttpApiImpl(siteSourceBean.getSiteHostUrl())
                        .postDirectly(url, headerMap, requestBody)
                        .execute().body().bytes(), charset);


            } else {
                content = new String(RetrofitHelper.getInstance().getHttpApiImpl(siteSourceBean.getSiteHostUrl())
                        .getDirectly(link, headerMap)
                        .execute().body().bytes(), charset);
            }
//            Set<String> utf8Set = new HashSet<>();
//            utf8Set.add("utf-8");
//            utf8Set.add("utf8");
//            //TODO 默认为不是utf8的就是gbk?
//            if (!utf8Set.contains(charset.toLowerCase())) {
//                content = EncodeUtils.getUTF8StringFromGBKString(content);
//            }
            return content;
        } catch (Exception e) {
            return "";
        }
    }
}
